<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2022/7/22 0022
 * Time: 15:11
 */

namespace framework\library;

class MiddleWare
{
    // 中间件队列
    protected $queue = [];
    protected $config = [
        'default_namespace' => 'app\\http\\middleware\\',
    ];

//    protected $middle = [
//        'Auth' => 'app\http\middleware\Auth::class'
//    ];

//    public function __construct()
//    {
//        // 中间件组装格式
//        $this->queue[] = [['app\http\middleware\Auth::class', 'handler'], null];
//        $this->queue[] = [['api\Test\testRoute::class', 'handler'], null];
//        $this->queue[] = [[function () {
//            return 12346;
//        }], null];
//    }

    // 分配
    public function dispatch($request)
    {
        return call_user_func($this->resolve(), $request);
    }

    // 分解中间件
    public function resolve($type = 'route')
    {
        $middlewareObj = $this;
        return function ($request) use ($type, $middlewareObj) {
            $middleware = array_shift($middlewareObj->queue[$type]);

            if ($middleware != null) {
                list($call, $param) = $middleware;
                return call_user_func_array($call, [$request, $this->resolve()]);
            }
        };
    }

    // 合并中间件
    public function merge($middleware, $type = "route")
    {
        $this->queue = array_merge($middleware, $this->queue[$type]);
    }

    // 添加到中间件队列
    public function add($middleware, $type = 'route')
    {
        foreach ($middleware as $key => $item) {
            $this->import($item, $type);
        }
    }

    // 导入中间件
    public function import($middleware, $type = 'route')
    {
        $newMiddleware = [];
        if ($middleware instanceof \Closure) {
            $newMiddleware = [$middleware, null];
        }else {
            $newMiddleware = [[new $middleware, 'handler'], null];
        }

        $this->queue[$type][] = $newMiddleware;
        return $this;
    }

    // 控制器中间件导入
    public function controller($middleware, $type = "controller")
    {
        return $this->import($middleware, $type);
    }

    public function getQueue($type = "route")
    {
        $queue = $this->queue;
        if ($type) {
            $queue = $this->queue[$type] ?? $queue;
        }
        return $queue;
    }

}